package com.study.common.cpprop.util;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @author mengxj
 */
public class CopyPropertiesUtil {

    public static <T, O> void copy(T t, O o){
        String setter = "set", getter = "get";
        Class<?> target = t.getClass();
        Class<?> object = o.getClass();
        Field[] fields = object.getDeclaredFields();
        for(Field field: fields){
            String fieldName = field.getName();
            Class<?> objectFieldType = field.getType();
            try {
                Field targetField = target.getDeclaredField(fieldName);
                if(!targetField.getType().equals(objectFieldType)){
                    System.out.println(String.format("目标对象ss %s 属性 与 源对象该属性类型不同，不能复制该属性", fieldName));
                    continue;
                }
            }catch (NoSuchFieldException e){
                System.out.println(String.format("目标对象没有 %s 属性，不能复制该属性", fieldName));
                continue;
            }
            String prop = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);;
            String objectSet = setter + prop;
            String targetGet = getter + prop;
            Method objectSetMethod = null, targetGetMethod = null;
            try {
                objectSetMethod = object.getDeclaredMethod(objectSet, objectFieldType);
                targetGetMethod = target.getDeclaredMethod(targetGet);
            } catch (NoSuchMethodException e) {
                System.out.println(String.format("目标对象/源对象 没有 %s 属性对应的get/set方法，不能复制该属性", fieldName));
                continue;
            }
            try {
                Object getPropValue = targetGetMethod.invoke(t);
                objectSetMethod.invoke(o, getPropValue);
            } catch (IllegalAccessException|InvocationTargetException e) {
                if(e instanceof IllegalAccessException){
                    System.out.println(String.format("无访问 目标对象/源对象 %s 属性对应的get/set方法 的权限（比如set是private修饰的），不能复制该属性", fieldName));
                }else {
                    System.out.println("反射调用失败");
                }
            }
        }
    }
}
